package org.wakeful.cfg;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.wakeful.conn.ConnectionProperties;
import org.wakeful.conn.Environment;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

/**
 *
 * @author atila camurca
 */
public class Configuration {

   private Document doc;
   private SAXBuilder builder;
   private Element root;
   private Properties properties;
   private List<String> environments;
   private String xmlfilename;
	private static final String DEFAULT_FILENAME = "/wakeful.cfg.xml";

   public Configuration() {
      this.properties = new Properties();
      this.xmlfilename = getClass().getResource(DEFAULT_FILENAME).getPath();
   }

   public String getXmlfilename() {
      return xmlfilename;
   }

   public void setXmlfilename(String xmlfilename) {
      this.xmlfilename = xmlfilename;
   }

   public void readFile() throws Exception {
      try {
         builder = new SAXBuilder();
         FileReader reader = new FileReader(this.xmlfilename);
         doc = builder.build(reader);
         reader.close();
         System.out.println("File read."); // just for DEBUG
      } catch (Exception e) {
         System.out.println("Erro message: " + e.getMessage()); // just for DEBUG
         throw new Exception("Could not read the wakeful.cfg.xml", e);
      }
   }

   public void addProperties() throws Exception {
      if (doc != null) {
         root = doc.getRootElement();
         List<Element> lProperties = root.getChildren();
         for (Element e : lProperties) {
            String key = e.getAttributeValue("name");
            String value = e.getText();
            properties.setProperty(key, value);
         }
      }
   }

   /**
    * Obtem dados do banco de dados a partir de arquivo xml.
    * @return ConnectionProperties or null
    */
   public ConnectionProperties getConnectionProperties() throws FileNotFoundException, Exception {
      try {
         readFile(); // read the wakeful.cfg.xml.
         addProperties(); // add the properties read from the file.

         ConnectionProperties cp = new ConnectionProperties();
         if (properties != null) {
            cp.setHost(properties.getProperty(Environment.HOST));
            cp.setPort(properties.getProperty(Environment.PORT));
            cp.setSchema(properties.getProperty(Environment.SCHEMA));
            cp.setUser(properties.getProperty(Environment.USER));
            cp.setPassword(properties.getProperty(Environment.PASSWORD));
            cp.setDbName(properties.getProperty(Environment.DB_NAME));
            cp.setDriverClass(properties.getProperty(Environment.DRIVER_CLASS));
            cp.setDialect(properties.getProperty(Environment.DIALECT));
         }
         return cp;
      } catch (Exception e) {
         return null;
      }
   }

   public void saveConnectionProperties(ConnectionProperties cp) throws Exception {
      try {
         Properties p = toProperties(cp);
         doc = new Document();
         root = new Element("wakeful-config");
         for (int i = 0; i < environments.size(); i++) {
            Element e = new Element("property");
            e.setAttribute("name", environments.get(i));
            // criptografar
            String encrypt = p.getProperty(environments.get(i));
            e.setText(Wed.encrypt(encrypt));
            System.out.println("name: " + environments.get(i));
            System.out.println("value: " + p.getProperty(environments.get(i)));
            System.out.println("");
            root.addContent(e);
         }
         XMLOutputter xout = new XMLOutputter();
         FileWriter writer = new FileWriter(this.xmlfilename, false);
         doc.setRootElement(root);
         xout.setFormat(Format.getPrettyFormat());
         xout.output(doc, writer);
         writer.flush();
         writer.close();
         System.out.println("wakeful.cfg.xml criado com sucesso.");
      } catch (Exception e) {
         System.out.println("Erro message: " + e.getMessage());
         e.printStackTrace();
         throw new Exception();
      }
   }

   private void initializeEnvironments() {
      if (environments == null) {
         environments = new ArrayList<String>();
         environments.add(Environment.HOST);
         environments.add(Environment.PORT);
         environments.add(Environment.SCHEMA);
         environments.add(Environment.USER);
         environments.add(Environment.PASSWORD);
         environments.add(Environment.DB_NAME);
         environments.add(Environment.DRIVER_CLASS);
         environments.add(Environment.DIALECT);
      }
   }

   private Properties toProperties(ConnectionProperties cp) {
      Properties p = new Properties();
      initializeEnvironments(); // poe os valores na lista de environments
      for (int i = 0; i < cp.size(); i++) {
         String key = environments.get(i);
         String value = cp.get(i);
         p.setProperty(key, value);
      }
      return p;
   }

   /**
    * 
    * @return
    */
   public static boolean hasConfigXmlFile(String filename) {
      return new File(filename).exists();
   }
}
